﻿// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
//#include "../../Repository/MyCplusplus/include/ThreadTimer.h"
//#include "ThreadTimerClass.h"
#include "Base.h"
#include <cstdlib>

typedef void (*Fun)(void);

template<class dst_type, class src_type>
dst_type pointer_cast(src_type src)
{
	return *static_cast<dst_type*>(static_cast<void*>(&src));
}

void vTableTestFunc();

int main()
{

	vTableTestFunc();
	return 0;
}



// ThreadTimerClass.h 的验证程序,验证完全ok
//int main()
//{
//	std::cout << "hello world! current thread id[" << std::this_thread::get_id() << "]" << std::endl;
//	ThreadTimerClass ttm;
//	ttm.startThread(400);
//	//ThreadTimerClass ttm1;
//	//ttm1.startThread(500);
//
//	int timer1 = ttm.startTimer(0, 500, [](void*) {
//		std::cout << "---> timer1 func be excuted!! thread id[" << std::this_thread::get_id() << "]" << std::endl;
//		//std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//	});
//
//	int timer2 = ttm.startTimer(0, 600, [](void*) {
//		std::cout << "---> timer2 func be excuted!! thread id[" << std::this_thread::get_id() << "]" << std::endl;
//		//std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//	});
//
//	std::this_thread::sleep_for(std::chrono::milliseconds(5000));		// 如果想要使用sleep函数,可以include <windows.h> 然后使用Sleep(1), 秒
//	std::cout << __FUNCTION__ << " ----> program end!" << std::endl;
//
//	ttm.stopTimer(timer1);
//	ttm.stopTimer(timer2);
//
//	ttm.stopThread();
//	//ttm1.stopThread();
//
//	return 0;
//}



// ThreadTimer.h 的验证程序,验证完全ok
//int main()
//{
//    std::cout << "Hello World!\n";
//
//	VIEW_COMMON::ThreadTimer ttm;
//	std::cout << "start thread ...\n" << std::endl;
//	ttm.startThread(400);
//
//	// test delay timer
//	//std::cout << "start delay timer 5 2 \n" << std::endl;
//	//int timer1 = ttm.startTimer(5000, 2000, [](void*) {
//	//	std::cout << "delay taimer 5 2 lambda be called!" << std::endl;
//	//});
//
//	// test normal timer
//	std::cout << "start normal timer 0 1 \n" << std::endl;
//	int timer2 = ttm.startTimer(0, 1000, [](void*) {
//		std::cout << "normal timer 0 1 lambda be called!" << std::endl;
//	});
//
//	//std::cout << "timer1 id: " << timer1 << " timer2 id: " << timer2 << std::endl;
//	std::this_thread::sleep_for(std::chrono::seconds(20));
//
//
//	//ttm.stopTimer(timer1);
//	//std::cout << "stop delay timer 5 2 \n" << std::endl;
//
//	ttm.stopTimer(timer2);
//	std::cout << "stop normal timer 0 1 \n" << std::endl;
//
//	ttm.stopThread();
//	std::cout << "stop thread!! \n" << std::endl;
//
//	std::cout << "success!\n " << std::endl;
//}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件

void vTableTestFunc()
{
	std::cout << __func__ << "-----> be called!" << std::endl;
	Base b;
	Base b1;
	Base b2;

	Fun pFun = nullptr;
	Fun pFun1 = nullptr;
	Fun pFun2 = nullptr;

	std::cout << "虚函数表地址: " << (intptr_t*)(&b) << std::endl;
	std::cout << "虚函数表-- 第一个函数地址: " << (int*) * (intptr_t*)(&b) << std::endl;
	std::cout << "虚函数表-- 第二个函数地址: " << *((int*) * (int*)(&b) + 1) << std::endl;
	std::cout << "第一个虚函数地址: " << pointer_cast<void*>(&(Base::foo_1)) << std::endl;
	std::cout << "成员函数地址: " << pointer_cast<void*>(&(Base::foo_3)) << std::endl;

	// invoke the func
	pFun = (Fun) * ((int*) * (int*)(&b) + 1);	// +0 是析构函数
	pFun();	// Base::foo_1---> be called!

	pFun1 = (Fun) * ((int*) * (int*)(&b) + 2);	// +0 是析构函数
	pFun1();	// Base::foo_2---> be called!

	//pFun2 = (Fun) * ((int*)(pointer_cast<void*>(&(Base::foo_3))));		// 失败
	//pFun2();

	Derive_1 d1;
	Derive_2 d2;

	b.foo_1();
	b.foo_2();
	d1.foo_1();
	d1.foo_2();
	d1.doo_1();
	Derive_1* pd1 = &d1;
	pd1->doo_1();
	d2.foo_1();
	d2.foo_2();

	Base* b3 = nullptr;
	b3->foo_3();
	b3->foo_1();
}
